#include "animation.h"

namespace SkyID
{

//- Animation -----------------------------------------------------------------

Animation::Animation(const Texture *texture, int32 frames, int32 fps, float x, float y, float w, float h) :
	Sprite(texture, x, y, w, h)
{
	LOG_ASSERT(frames && fps);
	mFrame = 0;
	mFrames = frames;
	mSpeed = 1.0f / fps;
	mTime = 0.0f;
	mX = x;
	mY = y;
	mPlaying = false;
	mDelta = 1;
	mMode = ANIM_FORWARD;
}

Animation::~Animation()
{
	//
}

void Animation::play()
{
	mPlaying = true;
	mTime = 0.0f;
	setMode(mMode);
}

void Animation::setMode(AnimationMode mode)
{
	mMode = mode;

	if(mMode & ANIM_BACKWARD)
	{
		mDelta = -1;
		setFrame(mFrames - 1);
	}
	else
	{
		mDelta = 1;
		setFrame(0);
	}
}

void Animation::update(float dt)
{
	if(!mPlaying) return;

	mTime += dt;
	while (mTime >= mSpeed)
	{
		if (mFrame + mDelta == mFrames)
			mPlaying = false;
		else if(mFrame + mDelta < 0)
			mPlaying = false;

		setFrame(mFrame+mDelta);
		mTime -= mSpeed;
	}
}

void Animation::setFrame(int32 frame)
{
	frame = frame % mFrames;
	if(frame < 0)
		frame = mFrames + frame;
	mFrame = frame;

	int32 columns = int32(mTexture->getWidth()) / uint32(mWidth);
	float x = mX+mFrame*mWidth, y = mY;
	if ((x+mWidth) > mTexture->getWidth())
	{
		frame -= int32(mTexture->getWidth()-mX) / int32(mWidth);
		x = mWidth * (frame%columns);
		y += mHeight * (1.0f + frame/columns);
	}

	setTextureRect(x, y, mWidth, mHeight);

	bool flipX = mFlipX, flipY = mFlipY;
	mFlipX = false;
	mFlipY = false;
	flip(flipX, flipY);
}

} // namespace SkyID
